/* 
	Plugin zaklada 'kary' na nick:
	CVAR:
	zban_active (domyslnie 1):
		1 - wlacza plugin, 
		0 - wylacza
	zban_action (domyslnie 2):
		0 - kill na respie na poczatku rundy
		1 - nie moze zadawac obrazen
		2 - zadaje obrazenia sobie
		3 - exit na poczatku rundy
	zban_with_amx (domyslnie 0):
		0 - brak integracji z amx_ban
		1 - przy komendzie amx_ban, jesli czas = 0 i powod zawiera "czit" lub "aktyw" 
		(wielkosc liter nie ma znaczenia) banuje nick
	zban_log (domyslnie 1)
		0 - logi o banach nie sa zapisywane
		1 - logi o banach sa zapisywane
		
	Komendy:
		amx_zban nick|#id - banuje gracza jesli gracz zostanie znaleziony
		amx_zunban pelny_nick(gdy gracza nie ma na serwerze) | nick | #id - jesli gracz ma bana to go odbanowuje
		amx_addzban pelny_nick - dodaje dany nick do zbanowanych
	
*/
//#define AMXBANS 1


#include <amxmodx>
#include <amxmisc>
#include <nvault>
#include <hamsandwich>

#if defined AMXBANS
	#include <amxbans_main>
#endif



#define PLUGIN "Zabijaka Nick Ban"
#define VERSION "1.0"
#define AUTHOR "Zabijaka"

#define NAME_SIZE 64
#define LOG_FILE "zban.log"

enum {
	ZBAN_ACTION_KILL = 0,
	ZBAN_ACTION_NO_DAMAGE = 1,
	ZBAN_ACTION_REVERSE = 2,
	ZBAN_ACTION_EXIT = 3
}

new g_vault;
new PlayerNames[36][NAME_SIZE];
new PlayerBanned[36];
new gCvarAction;
new gCVarActive;
#if defined AMXBANS
new gCVarAmxBans;
#endif
new gCVarLog;
new MAX_PLAYERS;

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR);
	MAX_PLAYERS = get_maxplayers();
	
	g_vault = nvault_open("ZabiNickBan");
	gCvarAction = register_cvar("zban_action", "1");
	gCVarActive = register_cvar("zban_active", "1");
	#if defined AMXBANS
	gCVarAmxBans = register_cvar("zban_with_amx", "0");
	#endif
	gCVarLog = register_cvar("zban_log", "1");
	
	register_concmd("amx_zban", "zBan", ADMIN_BAN, "nick lub #authid gracza na serwerze");
	register_concmd("amx_addzban", "addZBan", ADMIN_BAN, "pelny_nick gracza");
	register_concmd("amx_zunban", "zUnBan", ADMIN_BAN, "nick lub #authid gracza na serwerze; lub palny nick gracza");
	register_concmd("amx_zbanmenu", "zBanMenu", ADMIN_BAN);
	
	RegisterHam(Ham_TakeDamage, "player", "TakeDamage");
	RegisterHam(Ham_Spawn, "player", "Odrodzenie", 1);
}

#if defined AMXBANS

public amxbans_player_flagged(index, sec_left, reason[]){
	if(get_pcvar_num(gCVarAmxBans)){
		if(sec_left == 0 ){
			if(strfind(reason, "czit", 1) > -1 || 
				strfind(reason, "aktyw", 1) > -1){
				if(player && player < MAX_PLAYERS) {
					PlayerBanned[player] = 1;
					banName(-1, PlayerNames[player]);					
				}
			}
		}	
	}
}

#endif


public zBanMenu(id, level, cid){
	if(get_pcvar_num(gCVarActive)){
		if(cmd_access(id,level,cid,1)) {
			new menu = menu_create("\rZabijaka Ban Nemu:", "menu_handler");
			new players[32], pnum, tempid;
			new szName[32], szTempid[10];
			get_players(players, pnum);
			new s1 = charsmax(szName);
			new s2 = charsmax(szTempid);
			for( new i; i<pnum; i++ )
			{        
				tempid = players[i];
				get_user_name(tempid, szName, s1);
				num_to_str(tempid, szTempid, s2);
				menu_additem(menu, szName, szTempid, 0);
			}
			menu_display(id, menu, 0);
		}
	}
	return PLUGIN_HANDLED;
}
public menu_handler(id, menu, item)
{
	if( item == MENU_EXIT )
	{
		menu_destroy(menu);
		return PLUGIN_HANDLED;
	}

	new data[6], szName[64];
	new acc, callback;
	menu_item_getinfo(menu, item, acc, data, charsmax(data), szName, charsmax(szName), callback);
	new tempid = str_to_num(data);
	if(tempid > 0 && tempid < MAX_PLAYERS && is_user_connected(tempid) )
	{		
		banName(id, PlayerNames[tempid]);
	}

	menu_destroy(menu);
	return PLUGIN_HANDLED;
}





public client_authorized(id){
	new name[64];
	get_user_name(id, name, charsmax(name));
	strtoupper(name);
	copy(PlayerNames[id], NAME_SIZE -1, name);
	new value[2];
	new timestamp;
	
	if(nvault_lookup(g_vault, name, value, charsmax(value), timestamp) ) {
		PlayerBanned[id] = 1;	
	}
}

banName(id, const name[]){
	nvault_set(g_vault, name, "1");
	if(id){
		client_print(id, print_console, "[ZBAN] Gracz %s zbanowany", name);
		client_print(id, print_chat, "[ZBAN] Gracz %s zbanowany", name);
	}
	addLog(id, name, 1);
}

addLog(admin, const name[], ban =1){
	if(get_pcvar_num(gCVarLog)){
		new msg[128];
		if(admin){
			new aName[NAME_SIZE];
			get_user_name(admin, aName, NAME_SIZE - 1);
			new steam[NAME_SIZE];
			get_user_authid(admin, steam, NAME_SIZE - 1);
			format(msg, charsmax(msg), "Admin %s[Steam: %s]", aName, steam);
		} else {
			copy(msg,  charsmax(msg), "AMXBANS");
		}
		if(ban) {
			format(msg, charsmax(msg),"+ %s zabanowal %s",msg, name);
		} else {
			format(msg, charsmax(msg),"- %s odbanowal %s",msg, name);
		}
		log_to_file(LOG_FILE, msg);	
	}
}


public addZBan(id, level, cid){
	if(!get_pcvar_num(gCVarActive))
		return PLUGIN_HANDLED;
	if(!cmd_access(id,level,cid,2)) {
		return PLUGIN_HANDLED;
	}
	new argGracz[33];
	read_argv(1, argGracz, 32);
	banName(id, argGracz);
	return PLUGIN_HANDLED;
}


public zBan(id, level, cid){
	if(!get_pcvar_num(gCVarActive))
		return PLUGIN_HANDLED;
	if(!cmd_access(id,level,cid,2)) {
		return PLUGIN_HANDLED;
	}
	new argGracz[33];
	
	read_argv(1, argGracz, 32);
	
	new player = cmd_target(id, argGracz, CMDTARGET_ALLOW_SELF);
	if(player && player < MAX_PLAYERS) {
		PlayerBanned[player] = 1;
		banName(id, PlayerNames[player]);
	}
	
	return PLUGIN_HANDLED;
}

public zUnBan(id, level, cid){
	if(!get_pcvar_num(gCVarActive))
		return PLUGIN_HANDLED;
	if(!cmd_access(id,level,cid,2)) {
		return PLUGIN_HANDLED;
	}
	
	new name[33];
	read_argv(1, name, 32);
	new player = cmd_target(id, name, CMDTARGET_ALLOW_SELF);	
	
	new value[2];
	new timestamp;
	new i;
	new plName[NAME_SIZE];
	if( nvault_lookup(g_vault, name, value, charsmax(value), timestamp) ) {
		nvault_remove(g_vault, name);
		for(i=0;i< MAX_PLAYERS;i++){
			copy(plName, NAME_SIZE -1, PlayerNames[i]);
			if(equali(plName, name)){
				client_print(id, print_console, "[ZBAN] Gracz %s odbanowany", plName);
				client_print(id, print_chat, "[ZBAN] Gracz %s odbanowany", plName);
				PlayerBanned[i]=0;
				addLog(id, name, 0);
			}
		}
	} else {
		if(player && player < MAX_PLAYERS){
			PlayerBanned[player] = 0;
			copy(plName, NAME_SIZE -1, PlayerNames[player]);
			client_print(id, print_console, "[ZBAN] Gracz %s odbanowany",plName);
			client_print(id, print_chat, "[ZBAN] Gracz %s odbanowany", plName);
			nvault_remove(g_vault, PlayerNames[player]);
			addLog(id, plName, 0);
		}
	}
	return PLUGIN_HANDLED;
}

public client_disconnect(id){
	PlayerNames[id][0] = '^0';
	PlayerBanned[id] = 0;
}

public TakeDamage(id, idinflictor, idattacker, Float:damage, damagebits)
{
	if(!get_pcvar_num(gCVarActive))
		return HAM_IGNORED;
	if(idattacker < MAX_PLAYERS && id < MAX_PLAYERS){
		if(PlayerBanned[idattacker] && !PlayerBanned[id] ){
			new action = get_pcvar_num(gCvarAction)
			if(action == ZBAN_ACTION_REVERSE) {
				new health = get_user_health(idattacker)
				if(float(health) < damage) {
					ExecuteHam(Ham_Killed, idattacker, id, 0);
					return HAM_SUPERCEDE;
				} else {
					SetHamParamEntity(3, id);
					SetHamParamEntity(1, idattacker);
				}
			} else if (action == ZBAN_ACTION_NO_DAMAGE){
				SetHamParamFloat(4, 0.0);
			}
		}
	}
	return HAM_IGNORED;	
}

public Odrodzenie(id)
{
	if(!get_pcvar_num(gCVarActive))
		return PLUGIN_CONTINUE;
	if(!is_user_alive(id) || !is_user_connected(id) || id >= MAX_PLAYERS)
		return PLUGIN_CONTINUE;
	new action = get_pcvar_num(gCvarAction);
	if(PlayerBanned[id] && action == ZBAN_ACTION_KILL){
		client_cmd(id, "kill");
		return PLUGIN_CONTINUE;
	}
	if(PlayerBanned[id] && action == ZBAN_ACTION_EXIT){
		client_cmd(id, "exit");
		return PLUGIN_CONTINUE;
	}
	return PLUGIN_CONTINUE;
}


